﻿using System.ComponentModel;
using System.ComponentModel.Design;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PrismFactory.SoftwareFactory.Views.CreateSolution;
using PrismGuidancePackage.Views.Services;
using Rhino.Mocks;

namespace PrismGuidancePackage.Views.Tests
{
    [TestClass]
    public class EnsurePrismAssembliesPageViewModelFixture
    {
        private EnsurePrismAssembliesPageViewModel viewModel;
        private IDictionaryService stubDictionaryService;
        private IFileSystemService stubFileSystemService;

        [TestInitialize]
        public void Setup()
        {
            stubDictionaryService = MockRepository.GenerateStub<IDictionaryService>();
            stubFileSystemService = MockRepository.GenerateStub<IFileSystemService>();
            viewModel = new EnsurePrismAssembliesPageViewModel(stubDictionaryService, stubFileSystemService);
        }

        [TestMethod]
        public void ValidWhenPrismAssembliesPathForWpfExist()
        {
            const string path = "myPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(true);
            Assert.IsNull((viewModel as IDataErrorInfo)[EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey]);
        }

        [TestMethod]
        public void ValidWhenPrismAssembliesPathForSilverlighExist()
        {
            const string path = "myPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(true);
            Assert.IsNull((viewModel as IDataErrorInfo)[EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey]);
        }

        [TestMethod]
        public void InvalidWhenPrismAssembliesPathForWpfDoesNotExist()
        {
            const string path = "myPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(false);
            Assert.IsNotNull((viewModel as IDataErrorInfo)[EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey]);
        }

        [TestMethod]
        public void InvalidWhenPrismAssembliesPathForSilverlightDoesNotExist()
        {
            const string path = "myPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(false);
            Assert.IsNotNull((viewModel as IDataErrorInfo)[EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey]);
        }

        [TestMethod]
        public void SetsPrismAssembliesListForDesktop()
        {
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesWpfKey)).Return("a1;a2;a3");
            var assembliesForDesktop = viewModel.PrismAssembliesWpf;
            Assert.AreEqual(3, assembliesForDesktop.Count);
            Assert.AreEqual("a1", assembliesForDesktop[0].Name);
            Assert.AreEqual("a2", assembliesForDesktop[1].Name);
            Assert.AreEqual("a3", assembliesForDesktop[2].Name);
        }

        [TestMethod]
        public void SetsPrismAssembliesListForSilverlight()
        {
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesSilverlightKey)).Return("a1;a2;a3");
            var assembliesForSilberlight = viewModel.PrismAssembliesSilverlight;
            Assert.AreEqual(3, assembliesForSilberlight.Count);
            Assert.AreEqual("a1", assembliesForSilberlight[0].Name);
            Assert.AreEqual("a2", assembliesForSilberlight[1].Name);
            Assert.AreEqual("a3", assembliesForSilberlight[2].Name);
        }

        [TestMethod]
        public void SetsPrismAssembliesForDesktopExistenceBasedOnSpecifiedPath()
        {
            const string path = "NewPath";
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesWpfKey)).Return("a1;a2;a3");
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a1"))).Return(true);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a2"))).Return(false);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a3"))).Return(true);

            var assembliesForDesktop = viewModel.PrismAssembliesWpf;
            viewModel.PrismAssembliesPathWpf = path;
            Assert.IsTrue(assembliesForDesktop[0].Exists);
            Assert.IsFalse(assembliesForDesktop[1].Exists);
            Assert.IsTrue(assembliesForDesktop[2].Exists);
        }

        [TestMethod]
        public void SetsPrismAssembliesForSilverlighExistenceBasedOnSpecifiedPath()
        {
            const string path = "NewPath";
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesSilverlightKey)).Return("a1;a2;a3");
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a1"))).Return(false);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a2"))).Return(true);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a3"))).Return(false);

            var assembliesForSilverlight = viewModel.PrismAssembliesSilverlight;
            viewModel.PrismAssembliesPathSilverlight = path;
            Assert.IsFalse(assembliesForSilverlight[0].Exists);
            Assert.IsTrue(assembliesForSilverlight[1].Exists);
            Assert.IsFalse(assembliesForSilverlight[2].Exists);
        }

        [TestMethod]
        public void IsValidIsFalseWhenAtLeastOnePrimsAssemblyForDesktopIsNotFound()
        {
            const string path = "NewPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(true);

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesWpfKey)).Return("a1;a2;a3");
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a1"))).Return(true);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a2"))).Return(false);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a3"))).Return(true);

            Assert.IsFalse(viewModel.IsValid);
        }

        [TestMethod]
        public void IsValidIsFalseWhenAtLeastOnePrimsAssemblyForSilverlightIsNotFound()
        {
            const string path = "NewPath";

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathWpfKey)).Return(path);
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.PathExists(path)).Return(true);

            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesSilverlightKey)).Return("a1;a2;a3");
            stubDictionaryService.Stub(s => s.GetValue(EnsurePrismAssembliesPageViewModel.PrismAssembliesPathSilverlightKey)).Return(path);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a1"))).Return(true);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a2"))).Return(false);
            stubFileSystemService.Stub(s => s.FileExists(Path.Combine(path, "a3"))).Return(true);

            Assert.IsFalse(viewModel.IsValid);
        }
    }
}